﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Csla.Xaml;
using ProjTemp.Common.Logging;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using Microsoft.Practices.Prism.ViewModel;
using System.ComponentModel;
using Microsoft.Practices.Prism.Regions;
using System.ComponentModel.Composition;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.ServiceLocation;
using ProjTemp.Common;
using ProjTemp.Desktop.Common.View;
using Microsoft.Practices.Prism.Commands;
using System.Windows.Input;

namespace ProjTemp.Desktop.Common.ViewModel
{
    public class VMBase<T> : ViewModel<T>, IRegionMemberLifetime, INavigationAware, IConfirmNavigationRequest, IPresenter
    {
        protected readonly ILogger _logger;
        protected readonly IRegionManager _regionManager;
        protected readonly IEventAggregator _eventAggregator;
        protected readonly IServiceLocator _serviceLocator;

        protected VBase _view;
        protected object _header;

        public ICommand BeginRefreshCommand { get; protected set; }
        public ICommand RefreshCommand { get; protected set; }
        public ICommand AddNewCommand { get; protected set; }
        public ICommand BeginSaveCommand { get; protected set; }
        public ICommand SaveCommand { get; protected set; }
        public ICommand DeleteCommand { get; protected set; }
        public ICommand CancelCommand { get; protected set; }

        public VMBase(ILogger logger, IRegionManager regionManager, IEventAggregator eventAggregator, IServiceLocator serviceLocator)
        {
            this._header = string.Empty;
            this._logger = logger;
            this._regionManager = regionManager;
            this._eventAggregator = eventAggregator;
            this._serviceLocator = serviceLocator;
            //Commands
            this.BeginRefreshCommand = null;
            this.RefreshCommand = null;
            this.AddNewCommand = new DelegateCommand(() => DoAddNew(), () => CanAddNew);
            this.BeginSaveCommand = new DelegateCommand(BeginSave, () => CanSave);
            this.SaveCommand = new DelegateCommand(() => DoSave(), () => CanSave);
            this.DeleteCommand = new DelegateCommand(DoDelete, () => CanDelete);
            this.CancelCommand = new DelegateCommand(DoCancel, () => CanCancel);
        }

        /// <summary>
        /// Raises this object's PropertyChanged event.
        /// </summary>
        /// <typeparam name="T">The type of the property that has a new value</typeparam>
        /// <param name="propertyExpression">A Lambda expression representing the property that has a new value.</param>
        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Cannot change the signature")]
        protected void RaisePropertyChanged<P>(Expression<Func<P>> propertyExpression)
        {
            var propertyName = PropertySupport.ExtractPropertyName(propertyExpression);
            this.OnPropertyChanged(propertyName);
        }

        public VBase View
        {
            get { return this._view; }
            set { this._view = value; }
        }

        public object Header
        {
            get { return this._header; }
            set { this._header = value; this.RaisePropertyChanged(() => this.Header); }
        }

        public virtual bool KeepAlive
        {
            get { return false; }
        }

        public virtual bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return false;
        }

        public virtual void OnNavigatedFrom(NavigationContext navigationContext)
        {
        }

        public virtual void OnNavigatedTo(NavigationContext navigationContext)
        {
        }

        public virtual void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
        {
            if (continuationCallback != null)
                continuationCallback(true);
        }
    }
}
